package com.css.common.core.utils;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName BaseUtil
 * @Auther qiumengmeng
 * @Date 2024/7/10 下午10:56
 */
public class BaseUtil {
    private static final String[] dateFormatinfo = new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy年MM月dd日HH时mm分ss秒", "yyyy-MM-dd", "yyyy/MM/dd", "yy-MM-dd", "yy/MM/dd", "yyyy年MM月dd日", "HH:mm:ss", "yyyyMMddHHmmss", "yyyyMMdd", "yyyy.MM.dd", "yy.MM.dd", "yyyyMMddHHmmssSSS", "yyyy-MM-dd HH:mm:ss:SSS", "yyyy-MM-dd HH:mm:ss.SSS", "yyyy", "yyyyMM", "yyyyMMdd HH", "yyyyMMdd HH:mm", "yyyyMMdd HH:mm:ss"};
    private static final Snowflake SNOWFLAKE = IdUtil.getSnowflake(1, 1);

    /**
     * 获取long类型的id，雪花算法
     * @return id
     */
    public static Long getNextId(){
        return SNOWFLAKE.nextId();
    }


    /**
     * 获取异常内信息
     *
     * @param e 异常
     * @return 异常信息
     */
    public static String getExceptionInfo(Exception e) {
        final StringWriter sw = new StringWriter();
        final PrintWriter pw = new PrintWriter(sw, true);
        e.printStackTrace(pw);
        pw.flush();
        sw.flush();
        return sw.toString();
    }

    /**
     * 对象判空
     *
     * @param obj 判空对象
     * @return 是否为空
     */
    public static boolean isNull(Object obj) {
        boolean isNullFlag = true;
        if (obj != null) {
            if (obj instanceof List) {
                isNullFlag = isNull((List) obj);
            } else if (obj instanceof Set) {
                isNullFlag = isNull((Set) obj);
            } else if (obj instanceof Object[]) {
                isNullFlag = isNull((Object[]) ((Object[]) obj));
            } else if (obj instanceof Map) {
                isNullFlag = isNull((Map) obj);
            } else if (obj instanceof String) {
                isNullFlag = isNull((String) obj);
            } else {
                isNullFlag = false;
            }
        }

        return isNullFlag;
    }

    private static boolean isNull(List<?> list) {
        return list == null || list.size() == 0;
    }

    private static boolean isNull(Set<?> set) {
        return set == null || set.size() == 0;
    }

    private static boolean isNull(Object[] objects) {
        return objects == null || objects.length == 0;
    }

    private static boolean isNull(Map<?, ?> map) {
        return map == null || map.isEmpty();
    }

    private static boolean isNull(String str) {
        return str == null || "".equals(str.trim()) || "null".equalsIgnoreCase(str.trim());
    }

    /**
     * 对象判空
     *
     * @param obj 判空对象
     * @return 是否为空
     */
    public static boolean notNull(Object obj) {
        return !isNull(obj);
    }

    /**
     * 判断字段是否为空
     *
     * @param object 对象
     * @param fields 字段列表
     * @return boolean 返回字段是否为空的结果
     */
    public static boolean notNull(Object object, String... fields) {
        if (object == null) {
            return false;
        }
        for (String field : fields) {
            try {
                Field declaredField = object.getClass().getDeclaredField(field);
                declaredField.setAccessible(true);
                Object value = declaredField.get(object);
                if (isNull(value)) {
                    return false;
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 判断字段是否为空
     *
     * @param map    对象
     * @param fields 字段列表
     * @return boolean 返回字段是否为空的结果
     */
    public static boolean notNull(Map map, String... fields) {
        if (map == null) {
            return false;
        }
        for (String field : fields) {
            if (!map.containsKey(field) || isNull(map.get(field))) {
                return false;
            }
        }
        return true;
    }

    /**
     * @return String
     * @name 获取随机数
     */
    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            s.append(str.charAt(number));
        }
        return s.toString();
    }

    // 正则表达式来验证手机号码
    private static final String VALIDATION_PHONE = "^1[3-9]\\d{9}$";

    /**
     * 验证手机号码
     *
     * @param phoneNumber
     * @return
     */
    public static boolean isValidPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.isEmpty()) {
            return false;
        }
        return phoneNumber.matches(VALIDATION_PHONE);
    }

    /**
     * 将数据库的Object 强转为String
     *
     * @param object
     * @return
     */
    public static String object2Str(Object object) {
        String res = "";
        if (object != null) {
            if (object instanceof Double) {
                res = double2str((double) object);
            } else if (object instanceof Integer) {
                res = String.valueOf(object);
            } else if (object instanceof Timestamp) {
                Timestamp time = (Timestamp) object;
                res = dateToString(time, 0);
            } else if (object instanceof String || object instanceof Float || object instanceof BigDecimal) {
                res = String.valueOf(object);
            } else {
                res = String.valueOf(object);
            }
        }
        return res;
    }

    public static BigDecimal object2BigDecimal(Object obj){
        BigDecimal returnVal = null;
        if (obj != null) {
            if (!(obj instanceof Double) && !(obj instanceof Integer) && !(obj instanceof Long)) {
                if (obj instanceof BigDecimal) {
                    returnVal = (BigDecimal)obj;
                } else if (obj instanceof String) {
                    if (((String)obj).trim().length() == 0) {
                        returnVal = null;
                    } else {
                        returnVal = new BigDecimal(obj.toString());
                    }
                }
            } else {
                returnVal = new BigDecimal(obj.toString());
            }
        }

        return returnVal;
    }

    public static String double2str(double number) {
        DecimalFormat df = new DecimalFormat("#0.00");
        return df.format(number);
    }

    public static String dateToString(Date date, int format) {
        String dates = dateFormatinfo[format];
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dates);
        return simpleDateFormat.format(date);
    }
}
